package com.tzy.parser.core;

import com.tzy.parser.core.strategy.*;

import java.util.Deque;
import java.util.LinkedList;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;


public class AttributeParser implements Parser {

    private ConcurrentHashMap<String, TemplateStrategy> strategies;

    public AttributeParser() {
        this.strategies = new ConcurrentHashMap<>();
        init();
    }


    public void addStrategy(TemplateStrategy strategy) {
        strategies.putIfAbsent(strategy.strategyName(), strategy);
    }


    private void init() {

        //初始化默认策略
        addStrategy(new BasicTemplateStrategy());
        addStrategy(new ObjectTemplateStrategy(this));
        addStrategy(new LogicalTemplateStrategy(this));
        addStrategy(new ComputationTemplateStrategy(this));
        addStrategy(new CompareTemplateStrategy(this));
    }

    public Object parse(MetaObject obj, String template) {


        Deque<Integer> templateQueue = new LinkedList<>();

        StringBuilder stringBuilder = new StringBuilder(template);

        //判断是否有子表达式
        if (template.contains("(") && template.contains(")")) {

            int i = stringBuilder.indexOf("(");
            templateQueue.addLast(i);

            for (int j = i + 1; j < stringBuilder.length(); j++) {

                char nowChar = stringBuilder.charAt(j);

                if (nowChar == '(') {
                    templateQueue.addLast(j);
                }

                //找到一个完整的子表达式
                if (nowChar == ')') {
                    Integer integer = templateQueue.removeLast();

                    //integer  --->  j  位一个最小子表达式
                    String subTemplate = stringBuilder.substring(integer + 1, j);
                    Object value = toParse(obj, subTemplate);


                    //表达式 重定位
                    assert value != null;

                    String stringVal = value.toString();
                    int length = stringVal.length();
                    int k = integer + length;
                    stringBuilder.replace(integer, j + 1, stringVal);
                    j = k - 1;

                }
            }
        }


        return toParse(obj, stringBuilder.toString());
    }

    private Object toParse(MetaObject obj, String subTemplate) {

        Object meta = null;
        if (obj != null) {
            meta = obj.getObj();
        }


//        if(!subTemplate.startsWith(name)){
//            throw new MetaObjNameException(subTemplate+"  不是以 "+name+" 起始的");
//        }


        return baseParse(meta, subTemplate);
    }


    public Object baseParse(Object obj, String template) {

        for (TemplateStrategy strategy : strategies.values()) {

            if (strategy.canParse(template)) {
                return strategy.parse(template, obj);
            }
        }

        return null;
    }

    public Set<String> supportStrategyNames() {
        return strategies.keySet();
    }


    public TemplateStrategy getStrategy(String strategyName) {
        return strategies.get(strategyName);
    }


}
